<template>
    <div class="wh-100% flex flex-col items-center">
        <div class="w-full flex items-center justify-between gap-10px mb-20px">
            <n-select
                v-model:value="auditModel"
                :options="selectOptions"
                @update:value="(key: 'reserve' | 'cancel') => {auditModel = key; handleRefresh()}"
                class="w-120px"
            />
            <div class="flex items-center">
                <div v-if="verifyingReservations.length !== 0">
                    当前 {{ current + 1 }} / {{ pagination.total }}
                </div>
                <n-divider vertical />
                <n-button-group>
                    <n-button
                        secondary
                        :focusable="false"
                        @click="handleRefresh"
                    >
                        <template #icon>
                            <n-icon :component="ReloadCircle" :size="20" />
                        </template>
                        刷新
                    </n-button>
                    <n-button
                        secondary
                        type="primary"
                        :focusable="false"
                        :disabled="
                            verifyingReservations.length === 0 &&
                            verifyingCancellations.length === 0
                        "
                        @click="handleOperation('approved')"
                    >
                        <template #icon>
                            <n-icon :component="CheckmarkCircle" :size="20" />
                        </template>
                        通过
                    </n-button>
                    <n-button
                        secondary
                        type="error"
                        :focusable="false"
                        :disabled="
                            verifyingReservations.length === 0 &&
                            verifyingCancellations.length === 0
                        "
                        @click="handleOperation('rejected')"
                    >
                        <template #icon>
                            <n-icon :component="CloseCircle" :size="20" />
                        </template>
                        拒绝
                    </n-button>
                </n-button-group>
            </div>
        </div>
        <div
            v-if="
                auditModel === 'reserve'
                    ? currentReservation
                    : currentCancellation
            "
            class="flex gap-16px"
        >
            <!-- 左侧切换按钮 -->
            <div class="h-full w-80px flex-center left-wrapper">
                <n-icon-wrapper
                    color="#e8e7e6"
                    class="cursor-pointer"
                    :size="48"
                    :border-radius="50"
                    @click="handleItemChange('prev')"
                >
                    <n-icon :component="ChevronBack" :size="32" />
                </n-icon-wrapper>
            </div>
            <n-card class="w-500px h-600px" content-class="overflow-scroll">
                <ReservationDetail
                    v-if="
                        auditModel === 'reserve'
                            ? currentReservation
                            : currentCancellation
                    "
                    :model="auditModel"
                    :reservation="currentReservation!"
                    :cancellation="currentCancellation!"
                    :detail="currentReservationDetail!"
                />
            </n-card>
            <!-- 右侧切换按钮 -->
            <div class="h-full w-80px flex-center right-wrapper">
                <n-icon-wrapper
                    color="#e8e7e6"
                    class="cursor-pointer"
                    :size="48"
                    :border-radius="50"
                    @click="handleItemChange('next')"
                >
                    <n-icon :component="ChevronForward" :size="32" />
                </n-icon-wrapper>
            </div>
        </div>
        <div v-else class="h-300px flex-center">
            <n-result
                status="418"
                :title="
                    auditModel === 'reserve'
                        ? '暂无新的预约申请'
                        : '暂无新的取消申请'
                "
                description="一切尽在不言中"
            />
        </div>
    </div>
</template>

<script lang="ts" setup>
import { ref, reactive, onMounted } from "vue";

import type { Customer } from "@/service/api/types/user";
import type { MeetingRoom } from "@/service/api/types/room";
import type {
    Reservation,
    Cancellation,
    Order,
} from "@/service/api/types/reservation";

import {
    ReloadCircle,
    CheckmarkCircle,
    CloseCircle,
    ChevronBack,
    ChevronForward,
} from "@vicons/ionicons5";

import {
    auditReservation,
    getReservationById,
    getReservationCountsByStatus,
    getReservationsByStatus,
    getReservationDetail,
    auditCancellation,
    getCancellationCountsByStatus,
    getCancellationsByStatus,
} from "@/service/api/modules/reservation";
import ReservationDetail from "../components/reservation-detail/index.vue";

interface ReservationDetail {
    order: Order;
    customer: Customer;
    meetingRoom: MeetingRoom;
}

const current = ref(0);
const pagination = reactive({
    page: 1,
    size: 10,
    total: 0,
});
const selectOptions = [
    {
        label: "预约申请",
        value: "reserve",
    },
    {
        label: "取消申请",
        value: "cancel",
    },
];

const auditModel = ref<"reserve" | "cancel">("reserve");

const verifyingReservations = ref<Reservation[]>([]);
const verifyingCancellations = ref<Cancellation[]>([]);

const reservations: Map<string, Reservation> = new Map();
const reservationDetails: Map<string, ReservationDetail> = new Map();

const currentReservation = ref<Reservation>();
const currentCancellation = ref<Cancellation>();
const currentReservationDetail = ref<ReservationDetail>();

onMounted(async () => {
    handleRefresh();
});

// 加载下一页预约单
const getReservations = async () => {
    const reservations = await getReservationsByStatus(
        1,
        pagination.page++,
        pagination.size
    );
    verifyingReservations.value =
        verifyingReservations.value.concat(reservations);
};

// 加载下一页取消预约单
const getCancellations = async () => {
    const cancellations = await getCancellationsByStatus(
        1,
        pagination.page++,
        pagination.size
    );
    verifyingCancellations.value =
        verifyingCancellations.value.concat(cancellations);
};

// 获取预约单
const getReservationById_ = async (id: string) => {
    const reservation = await getReservationById(id);
    reservations.set(id, reservation);
    return reservation;
};

// 获取预约单详情
const getReservationDetail_ = async (id: string) => {
    const detail = await getReservationDetail(id);
    reservationDetails.set(id, detail);
    return detail;
};

const handleItemChange = async (action: "prev" | "next") => {
    if (action === "prev" && current.value === 0) {
        window.NMessage.info("这是第一条");
        return;
    }
    if (action === "next" && current.value + 1 === pagination.total) {
        window.NMessage.info("没有更多了");
        return;
    }
    current.value = action === "prev" ? current.value - 1 : current.value + 1;
    if (auditModel.value === "reserve") {
        if (current.value >= pagination.page * pagination.size) {
            await getReservations();
        }
        const reservation = verifyingReservations.value[current.value]!;
        if (!reservationDetails.has(reservation.id)) {
            await getReservationDetail_(reservation.id);
        }
        currentReservationDetail.value = reservationDetails.get(
            reservation.id
        )!;
        currentReservation.value = reservation;
    }
};

const handleRefresh = async () => {
    // 重置状态
    current.value = 0;
    pagination.page = 1;
    verifyingReservations.value = [];
    verifyingCancellations.value = [];
    reservations.clear();
    reservationDetails.clear();
    currentReservation.value = undefined;
    currentCancellation.value = undefined;
    currentReservationDetail.value = undefined;
    try {
        if (auditModel.value === "reserve") {
            // 重新获取预约单
            pagination.total = await getReservationCountsByStatus(1);
            if (pagination.total === 0) return;

            await getReservations(); // 先加载第一页预约单
            const reservation = verifyingReservations.value[current.value]; // 获取第一条预约单信息
            await getReservationDetail_(reservation.id); // 获取第一条预约单详情
            currentReservationDetail.value = reservationDetails.get(
                reservation.id
            );
            currentReservation.value = reservation;
        } else {
            // 重新获取取消单
            pagination.total = await getCancellationCountsByStatus(1);
            if (pagination.total === 0) return;

            await getCancellations(); // 先加载第一页取消单
            const cancellation = verifyingCancellations.value[current.value]; // 获取第一条取消单信息
            const reservation = await getReservationById_(
                cancellation.reservationId
            );
            await getReservationDetail_(reservation.id); // 获取第一条取消单对应的预约单信息
            currentReservationDetail.value = reservationDetails.get(
                reservation.id
            );
            currentCancellation.value = cancellation;
            currentReservation.value = reservation;
        }
    } catch (err) {
        window.NMessage.error((err as Error).message);
    }
};

const handleOperateReservation = (
    title: string,
    content: string,
    callback: () => void
) => {
    window.NDialog.info({
        title,
        content,
        closable: false,
        positiveText: "确认",
        negativeText: "取消",
        onPositiveClick: callback,
    });
};

const handleOperation = async (operation: "rejected" | "approved") => {
    if (auditModel.value === "reserve") {
        const id = currentReservation.value!.id;
        const title = operation === "approved" ? "通过" : "拒绝";
        const content =
            operation === "approved"
                ? "确认通过该预约申请吗？"
                : "确认拒绝该预约申请吗？";
        handleOperateReservation(title, content, async () => {
            try {
                await auditReservation(
                    id,
                    operation === "approved" ? "confirmed" : "rejected"
                );
                window.NMessage.success("操作成功");
                await handleRefresh(); // 刷新页面
            } catch (err) {
                window.NMessage.error((err as Error).message);
            }
        });
    } else {
        const id = currentCancellation.value!.id;
        const title = operation === "approved" ? "通过" : "拒绝";
        const content =
            operation === "approved"
                ? "确认通过该取消申请吗？"
                : "确认拒绝该取消申请吗？";
        handleOperateReservation(title, content, async () => {
            try {
                await auditCancellation(id, operation);
                window.NMessage.success("操作成功");
                await handleRefresh(); // 刷新页面
            } catch (err) {
                window.NMessage.error((err as Error).message);
            }
        });
    }
};
</script>

<style scoped></style>
